React Fiber-இன் முன்னுரிமைப் பாதை மேலாண்மையில் தேர்ச்சி பெற்று, தடையற்ற பயனர் இடைமுகங்களைத் திறந்திடுங்கள். கன்கரண்ட் ரெண்டரிங், ஷெட்யூலர், மற்றும் startTransition போன்ற புதிய API-கள் பற்றிய ஒரு விரிவான வழிகாட்டி.
React Fiber முன்னுரிமைப் பாதை மேலாண்மை: ரெண்டரிங் கட்டுப்பாட்டில் ஒரு ஆழமான பார்வை
இணைய மேம்பாட்டு உலகில், பயனர் அனுபவமே மிக முக்கியமானது. ஒரு நொடிப்பொழுது ஏற்படும் முடக்கம், ஒரு தடுமாறும் அனிமேஷன், அல்லது ஒரு மெதுவான உள்ளீட்டுப் புலம் ஆகியவை ஒரு மகிழ்ச்சியான பயனருக்கும் ஒரு விரக்தியடைந்த பயனருக்கும் இடையிலான வித்தியாசமாக இருக்கலாம். பல ஆண்டுகளாக, டெவலப்பர்கள் உலாவியின் ஒற்றைத்-திரி (single-threaded) தன்மையுடன் போராடி, தடையற்ற, பதிலளிக்கக்கூடிய செயலிகளை உருவாக்க முயன்றனர். React 16-இல் ஃபைபர் கட்டமைப்பின் அறிமுகம் மற்றும் React 18-இல் அதன் முழுமையான கன்கரண்ட் அம்சங்களுடன், இந்த ஆட்டம் அடிப்படையில் மாறியுள்ளது. React, பயனர் இடைமுகங்களை (UIs) வெறுமனே ரெண்டர் செய்யும் ஒரு லைப்ரரியில் இருந்து, UI புதுப்பிப்புகளை புத்திசாலித்தனமாக திட்டமிடும் (schedules) ஒன்றாக உருவெடுத்துள்ளது.
இந்த ஆழமான பார்வை, இந்த பரிணாம வளர்ச்சியின் இதயப் பகுதியான React Fiber-இன் முன்னுரிமைப் பாதை மேலாண்மையை ஆராய்கிறது. எதை இப்போது ரெண்டர் செய்வது, எது காத்திருக்கலாம், மற்றும் பயனர் இடைமுகத்தை முடக்காமல் பல நிலை புதுப்பிப்புகளை React எப்படி கையாள்கிறது என்பதை நாங்கள் தெளிவுபடுத்துவோம். இது ஒரு கோட்பாட்டுப் பயிற்சி மட்டுமல்ல; இந்த அடிப்படைக் கொள்கைகளைப் புரிந்துகொள்வது, உலகளாவிய பார்வையாளர்களுக்காக வேகமான, புத்திசாலித்தனமான, மற்றும் மீள்தன்மையுடைய செயலிகளை உருவாக்க உங்களுக்கு அதிகாரம் அளிக்கிறது.
ஸ்டாக் ரீகன்சைலரிலிருந்து ஃபைபர் வரை: மறுஎழுத்தின் பின்னணியில் உள்ள 'ஏன்'
ஃபைபரின் புதுமையைப் பாராட்ட, அதன் முன்னோடியான ஸ்டாக் ரீகன்சைலரின் வரம்புகளை நாம் முதலில் புரிந்து கொள்ள வேண்டும். React 16-க்கு முன்பு, ரீகன்சிலியேஷன் செயல்முறை—அதாவது, DOM-இல் எதை மாற்றுவது என்பதைத் தீர்மானிக்க ஒரு மரத்தை மற்றொன்றுடன் ஒப்பிட்டுப் பார்க்க React பயன்படுத்தும் அல்காரிதம்—ஒத்திசைவானதாகவும் (synchronous) மற்றும் ரிகர்சிவ்வாகவும் (recursive) இருந்தது. ஒரு காம்போனென்ட்டின் நிலை புதுப்பிக்கப்படும்போது, React முழு காம்போனென்ட் மரத்தையும் கடந்து, மாற்றங்களைக் கணக்கிட்டு, அவற்றை ஒரே, தடையற்ற வரிசையில் DOM-இல் பயன்படுத்தும்.
சிறிய செயலிகளுக்கு இது போதுமானதாக இருந்தது. ஆனால் ஆழமான காம்போனென்ட் மரங்களைக் கொண்ட சிக்கலான UI-களுக்கு, இந்த செயல்முறை கணிசமான நேரத்தை எடுக்கக்கூடும்—சொல்லப்போனால், 16 மில்லி வினாடிகளுக்கு மேல். ஜாவாஸ்கிரிப்ட் ஒற்றைத்-திரி என்பதால், நீண்ட நேரம் இயங்கும் ரீகன்சிலியேஷன் பணி பிரதான திரியை (main thread) தடுத்துவிடும். இதன் பொருள், உலாவி மற்ற முக்கியமான பணிகளைக் கையாள முடியாது, அவையாவன:
- பயனர் உள்ளீடுகளுக்குப் பதிலளிப்பது (தட்டச்சு செய்வது அல்லது கிளிக் செய்வது போன்றவை).
- அனிமேஷன்களை இயக்குவது (CSS அல்லது ஜாவாஸ்கிரிப்ட் அடிப்படையிலானது).
- மற்ற நேர-உணர்திறன் கொண்ட லாஜிக்கை செயல்படுத்துவது.
இதன் விளைவாக "ஜேங்க்" (jank) எனப்படும் ஒரு நிகழ்வு ஏற்பட்டது—இது ஒரு தடுமாறும், பதிலளிக்காத பயனர் அனுபவத்தைக் குறிக்கிறது. ஸ்டாக் ரீகன்சைலர் ஒரு ஒற்றைத்-தட இருப்புப்பாதை போல செயல்பட்டது: ஒரு ரயில் (ஒரு ரெண்டர் புதுப்பிப்பு) தனது பயணத்தைத் தொடங்கியவுடன், அது முடிவடையும் வரை ஓட வேண்டும், வேறு எந்த ரயிலும் அந்தத் தடத்தைப் பயன்படுத்த முடியாது. இந்தத் தடுக்கும் தன்மைதான் React-இன் முக்கிய அல்காரிதத்தை முழுமையாக மீண்டும் எழுத முதன்மைக் காரணமாக அமைந்தது.
React Fiber-க்குப் பின்னால் உள்ள முக்கிய யோசனை, ரீகன்சிலியேஷனை சிறிய வேலைகளாகப் பிரிக்கக்கூடிய ஒன்றாக மறுவடிவமைப்பதாகும். ஒரு ஒற்றை, பிரிக்க முடியாத பணியாக இல்லாமல், ரெண்டரிங்கை இடைநிறுத்தலாம், மீண்டும் தொடங்கலாம், ஏன் ரத்து கூட செய்யலாம். ஒத்திசைவிலிருந்து ஒத்திசைவற்ற, திட்டமிடக்கூடிய செயல்முறைக்கு இந்த மாற்றம், React-ஐ உலாவியின் பிரதான திரிக்கு கட்டுப்பாட்டைத் తిరిగి அளிக்க அனுமதிக்கிறது, இது பயனர் உள்ளீடு போன்ற உயர்-முன்னுரிமைப் பணிகள் ஒருபோதும் தடுக்கப்படாமல் இருப்பதை உறுதி செய்கிறது. ஃபைபர், ஒற்றைத்-தட இருப்புப்பாதையை உயர்-முன்னுரிமைப் போக்குவரத்திற்கு எக்ஸ்பிரஸ் பாதைகளைக் கொண்ட பல-வழிச் சாலையாக மாற்றியது.
'ஃபைபர்' என்றால் என்ன? கன்கரன்சியின் அடிப்படைக் கட்டமைப்பு
அதன் மையத்தில், ஒரு "ஃபைபர்" என்பது ஒரு வேலை அலகைக் (unit of work) குறிக்கும் ஒரு ஜாவாஸ்கிரிப்ட் ஆப்ஜெக்ட் ஆகும். இது ஒரு காம்போனென்ட், அதன் உள்ளீடு (props), மற்றும் அதன் வெளியீடு (children) பற்றிய தகவல்களைக் கொண்டுள்ளது. ஒரு ஃபைபரை நீங்கள் ஒரு விர்ச்சுவல் ஸ்டாக் ஃபிரேமாக நினைக்கலாம். பழைய ஸ்டாக் ரீகன்சைலரில், உலாவியின் கால் ஸ்டாக், ரிகர்சிவ் மரம் கடத்தலைக் கையாளப் பயன்படுத்தப்பட்டது. ஃபைபர் மூலம், React தனது சொந்த விர்ச்சுவல் ஸ்டாக்கை செயல்படுத்துகிறது, இது ஃபைபர் முனைகளின் இணைக்கப்பட்ட பட்டியலாக (linked list) குறிப்பிடப்படுகிறது. இது React-க்கு ரெண்டரிங் செயல்முறையின் மீது முழுமையான கட்டுப்பாட்டைக் கொடுக்கிறது.
உங்கள் காம்போனென்ட் மரத்தில் உள்ள ஒவ்வொரு உறுப்புக்கும் அதற்கேற்ற ஃபைபர் முனை உள்ளது. இந்த முனைகள் ஒன்றோடொன்று இணைக்கப்பட்டு ஒரு ஃபைபர் மரத்தை உருவாக்குகின்றன, இது காம்போனென்ட் மரத்தின் கட்டமைப்பைப் பிரதிபலிக்கிறது. ஒரு ஃபைபர் முனை முக்கியமான தகவல்களைக் கொண்டுள்ளது, அவற்றுள்:
- type and key: காம்போனென்ட்டிற்கான அடையாளங்காட்டிகள், நீங்கள் ஒரு React உறுப்பில் காண்பதைப் போன்றவை.
- child: அதன் முதல் குழந்தை ஃபைபருக்கான ஒரு சுட்டி.
- sibling: அதன் அடுத்த உடன்பிறப்பு ஃபைபருக்கான ஒரு சுட்டி.
- return: அதன் பெற்றோர் ஃபைபருக்கான ஒரு சுட்டி (வேலையை முடித்த பிறகு 'திரும்பும்' பாதை).
- pendingProps and memoizedProps: முந்தைய மற்றும் அடுத்த ரெண்டரின் ப்ராப்ஸ், வேறுபாட்டைக் கண்டறியப் பயன்படுகிறது.
- stateNode: உண்மையான DOM முனை, கிளாஸ் இன்ஸ்டன்ஸ், அல்லது அடிப்படை பிளாட்ஃபார்ம் உறுப்புக்கான ஒரு குறிப்பு.
- effectTag: செய்யப்பட வேண்டிய வேலையை விவரிக்கும் ஒரு பிட்மாஸ்க் (எ.கா., Placement, Update, Deletion).
இந்தக் கட்டமைப்பு, நேட்டிவ் ரிகர்ஷனைச் சாராமல் மரத்தைக் கடக்க React-ஐ அனுமதிக்கிறது. இது ஒரு ஃபைபரில் வேலையைத் தொடங்கி, இடைநிறுத்தி, பின்னர் அதன் இடத்தை இழக்காமல் மீண்டும் தொடங்க முடியும். வேலையை இடைநிறுத்தி மீண்டும் தொடங்கும் இந்தத் திறனே React-இன் அனைத்து கன்கரண்ட் அம்சங்களையும் இயக்கும் அடிப்படைக் பொறிமுறையாகும்.
கட்டமைப்பின் இதயம்: ஷெட்யூலர் மற்றும் முன்னுரிமை நிலைகள்
ஃபைபர்கள் வேலை அலகுகளாக இருந்தால், ஷெட்யூலர் தான் எந்த வேலையை எப்போது செய்வது என்பதைத் தீர்மானிக்கும் மூளையாகும். React ஒரு நிலை மாற்றம் ஏற்பட்டவுடன் உடனடியாக ரெண்டரிங்கைத் தொடங்குவதில்லை. மாறாக, அது புதுப்பிப்புக்கு ஒரு முன்னுரிமை அளவை ஒதுக்கி, அதை ஷெட்யூலரிடம் கையாளச் சொல்கிறது. ஷெட்யூலர் பின்னர் உலாவியுடன் இணைந்து வேலையைச் செய்ய சிறந்த நேரத்தைக் கண்டறிகிறது, அது முக்கியமான பணிகளைத் தடுக்காமல் இருப்பதை உறுதி செய்கிறது.
ஆரம்பத்தில், இந்த அமைப்பு தனித்தனி முன்னுரிமை நிலைகளின் தொகுப்பைப் பயன்படுத்தியது. நவீன செயலாக்கம் (லேன் மாடல்) மிகவும் நுணுக்கமானது என்றாலும், இந்த கருத்தியல் நிலைகளைப் புரிந்துகொள்வது ஒரு சிறந்த தொடக்கப் புள்ளியாகும்:
- ImmediatePriority: இது மிக உயர்ந்த முன்னுரிமை, உடனடியாக நடக்க வேண்டிய ஒத்திசைவான புதுப்பிப்புகளுக்காக ஒதுக்கப்பட்டுள்ளது. ஒரு சிறந்த உதாரணம் ஒரு கட்டுப்பாட்டிலுள்ள உள்ளீடு (controlled input). ஒரு பயனர் உள்ளீட்டுப் புலத்தில் தட்டச்சு செய்யும்போது, UI அந்த மாற்றத்தை உடனடியாகப் பிரதிபலிக்க வேண்டும். அது சில மில்லி வினாடிகள் தாமதமானால் கூட, உள்ளீடு மெதுவாக இருப்பதாக உணரப்படும்.
- UserBlockingPriority: ஒரு பட்டனைக் கிளிக் செய்வது அல்லது திரையைத் தட்டுவது போன்ற தனிப்பட்ட பயனர் தொடர்புகளின் விளைவாக ஏற்படும் புதுப்பிப்புகளுக்கு இதுவாகும். இவை பயனருக்கு உடனடியாகத் தெரிய வேண்டும், ஆனால் தேவைப்பட்டால் மிகக் குறுகிய காலத்திற்குத் தள்ளிப் போடப்படலாம். பெரும்பாலான நிகழ்வு கையாளுநர்கள் (event handlers) இந்த முன்னுரிமையில் புதுப்பிப்புகளைத் தூண்டுகின்றன.
- NormalPriority: தரவுப் பெறுதல் (`useEffect`) அல்லது வழிசெலுத்தல் போன்றவற்றிலிருந்து உருவாகும் பெரும்பாலான புதுப்பிப்புகளுக்கான இயல்புநிலை முன்னுரிமை இதுவாகும். இந்த புதுப்பிப்புகள் உடனடியாக இருக்கத் தேவையில்லை, மேலும் பயனர் தொடர்புகளில் குறுக்கிடுவதைத் தவிர்க்க React இவற்றைத் திட்டமிடலாம்.
- LowPriority: திரைக்கு வெளியே உள்ள உள்ளடக்கத்தை ரெண்டர் செய்வது அல்லது பகுப்பாய்வு நிகழ்வுகள் (analytics events) போன்ற நேர-உணர்திறன் இல்லாத புதுப்பிப்புகளுக்கு இதுவாகும்.
- IdlePriority: மிகக் குறைந்த முன்னுரிமை, உலாவி முற்றிலும் சும்மா இருக்கும்போது மட்டுமே செய்யக்கூடிய வேலைகளுக்கு. இது பயன்பாட்டுக் குறியீட்டால் அரிதாகவே நேரடியாகப் பயன்படுத்தப்படுகிறது, ஆனால் பதிவு செய்தல் அல்லது எதிர்கால வேலைகளை முன்கூட்டியே கணக்கிடுதல் போன்றவற்றுக்கு உள்நாட்டில் பயன்படுத்தப்படுகிறது.
புதுப்பிப்பின் சூழலைப் பொறுத்து React சரியான முன்னுரிமையை தானாகவே ஒதுக்குகிறது. எடுத்துக்காட்டாக, ஒரு `click` நிகழ்வு கையாளுநருக்குள் ஒரு புதுப்பிப்பு `UserBlockingPriority` ஆக திட்டமிடப்படுகிறது, அதே நேரத்தில் `useEffect`-க்குள் ஒரு புதுப்பிப்பு பொதுவாக `NormalPriority` ஆக இருக்கும். இந்த புத்திசாலித்தனமான, சூழல்-சார்ந்த முன்னுரிமையே React-ஐ இயல்பாகவே வேகமாக உணர வைக்கிறது.
லேன் கோட்பாடு: நவீன முன்னுரிமை மாடல்
React-இன் கன்கரண்ட் அம்சங்கள் மிகவும் அதிநவீனமாக மாறியதால், எளிய எண் முன்னுரிமை அமைப்பு போதுமானதாக இல்லை. வெவ்வேறு முன்னுரிமைகளின் பல புதுப்பிப்புகள், குறுக்கீடுகள் மற்றும் பேட்சிங் போன்ற சிக்கலான சூழ்நிலைகளை அது நேர்த்தியாகக் கையாள முடியவில்லை. இது **லேன் மாடலின்** வளர்ச்சிக்கு வழிவகுத்தது.
ஒற்றை முன்னுரிமை எண்ணுக்குப் பதிலாக, 31 "லேன்களின்" தொகுப்பைப் பற்றி சிந்தியுங்கள். ஒவ்வொரு லேனும் ஒரு ভিন্ন முன்னுரிமையைக் குறிக்கிறது. இது ஒரு பிட்மாஸ்க் (bitmask) ஆக செயல்படுத்தப்படுகிறது—ஒரு 31-பிட் முழு எண், இதில் ஒவ்வொரு பிட்டும் ஒரு லேனுக்கு ஒத்திருக்கிறது. இந்த பிட்மாஸ்க் அணுகுமுறை மிகவும் திறமையானது மற்றும் சக்திவாய்ந்த செயல்பாடுகளை அனுமதிக்கிறது:
- பல முன்னுரிமைகளைக் குறித்தல்: ஒரு ஒற்றை பிட்மாஸ்க் நிலுவையில் உள்ள முன்னுரிமைகளின் தொகுப்பைக் குறிக்க முடியும். எடுத்துக்காட்டாக, ஒரு `UserBlocking` புதுப்பிப்பு மற்றும் ஒரு `Normal` புதுப்பிப்பு இரண்டும் ஒரு காம்போனென்ட்டில் நிலுவையில் இருந்தால், அதன் `lanes` ப்ராப்பர்ட்டியில் அந்த இரண்டு முன்னுரிமைகளுக்குமான பிட்கள் 1 ஆக அமைக்கப்பட்டிருக்கும்.
- மேல்பொருந்துதலைச் சரிபார்த்தல்: பிட்வைஸ் செயல்பாடுகள், இரண்டு லேன் தொகுப்புகள் ஒன்றோடொன்று பொருந்துகின்றனவா அல்லது ஒரு தொகுப்பு மற்றொன்றின் துணைக்குழுவா என்பதைச் சரிபார்ப்பதை எளிதாக்குகின்றன. உள்வரும் புதுப்பிப்பை ஏற்கனவே உள்ள வேலையுடன் இணைக்க முடியுமா என்பதைத் தீர்மானிக்க இது பயன்படுத்தப்படுகிறது.
- வேலைக்கு முன்னுரிமை அளித்தல்: React நிலுவையில் உள்ள லேன்களின் தொகுப்பில் உள்ள மிக உயர்ந்த-முன்னுரிமை லேனை விரைவாகக் கண்டறிந்து, அதில் மட்டும் வேலை செய்யத் தேர்வு செய்யலாம், தற்போதைக்கு குறைந்த-முன்னுரிமை வேலைகளைப் புறக்கணிக்கலாம்.
ஒரு ஒப்புமை, 31 லேன்கள் கொண்ட ஒரு நீச்சல் குளமாக இருக்கலாம். ஒரு போட்டி நீச்சல் வீரர் போன்ற அவசரப் புதுப்பிப்பு, உயர்-முன்னுரிமை லேனைப் பெற்று, குறுக்கீடு இல்லாமல் தொடரலாம். சாதாரண நீச்சல் வீரர்கள் போன்ற பல அவசரமில்லாத புதுப்பிப்புகள், குறைந்த-முன்னுரிமை லேனில் ஒன்றாக இணைக்கப்படலாம். ஒரு போட்டி நீச்சல் வீரர் திடீரென்று வந்தால், உயிர் காப்பாளர்கள் (ஷெட்யூலர்) முன்னுரிமை நீச்சல் வீரர் கடந்து செல்ல சாதாரண நீச்சல் வீரர்களை இடைநிறுத்தலாம். லேன் மாடல், இந்த சிக்கலான ஒருங்கிணைப்பைக் கையாள React-க்கு மிகவும் நுணுக்கமான மற்றும் நெகிழ்வான அமைப்பை வழங்குகிறது.
இரண்டு-கட்ட ரீகன்சிலியேஷன் செயல்முறை
React Fiber-இன் மேஜிக் அதன் இரண்டு-கட்ட கமிட் கட்டமைப்பு மூலம் உணரப்படுகிறது. இந்த பிரிவினையே ரெண்டரிங்கை குறுக்கிடக்கூடியதாக மாற்றி, காட்சி முரண்பாடுகளை ஏற்படுத்தாமல் தடுக்கிறது.
கட்டம் 1: ரெண்டர்/ரீகன்சிலியேஷன் கட்டம் (ஒத்திசைவற்ற மற்றும் குறுக்கிடக்கூடியது)
இங்குதான் React கடினமான வேலையைச் செய்கிறது. காம்போனென்ட் மரத்தின் மூலத்திலிருந்து தொடங்கி, React ஒரு `workLoop`-இல் ஃபைபர் முனைகளைக் கடந்து செல்கிறது. ஒவ்வொரு ஃபைபருக்கும், அது புதுப்பிக்கப்பட வேண்டுமா என்பதை அது தீர்மானிக்கிறது. அது உங்கள் காம்போனென்ட்களை அழைத்து, புதிய உறுப்புகளை பழைய ஃபைபர்களுடன் ஒப்பிட்டு, பக்க விளைவுகளின் (side effects) பட்டியலை உருவாக்குகிறது (எ.கா., "இந்த DOM முனையைச் சேர்", "இந்த பண்பை புதுப்பி", "இந்த காம்போனென்ட்டை அகற்று").
இந்தக் கட்டத்தின் முக்கிய அம்சம் என்னவென்றால், அது ஒத்திசைவற்றது மற்றும் குறுக்கிடப்படலாம். சில ஃபைபர்களைச் செயலாக்கிய பிறகு, React தனக்கு ஒதுக்கப்பட்ட நேரத் துண்டு (வழக்கமாக சில மில்லி வினாடிகள்) தீர்ந்துவிட்டதா என்பதை `shouldYield` என்ற உள் செயல்பாடு மூலம் சரிபார்க்கிறது. ஒரு உயர்-முன்னுரிமை நிகழ்வு (பயனர் உள்ளீடு போன்றவை) ஏற்பட்டால் அல்லது அதன் நேரம் முடிந்தால், React தனது வேலையை இடைநிறுத்தி, அதன் முன்னேற்றத்தை ஃபைபர் மரத்தில் சேமித்து, கட்டுப்பாட்டை உலாவியின் பிரதான திரிக்குத் திருப்பித் தரும். உலாவி மீண்டும் சுதந்திரமாக ஆனதும், React தான் விட்ட இடத்திலிருந்து மீண்டும் தொடங்கலாம்.
இந்த முழு கட்டத்திலும், எந்த மாற்றங்களும் DOM-இல் பதியப்படுவதில்லை. பயனர் பழைய, சீரான UI-ஐப் பார்க்கிறார். இது மிகவும் முக்கியமானது—React மாற்றங்களை படிப்படியாகப் பயன்படுத்தினால், பயனர் ஒரு உடைந்த, பாதி ரெண்டர் செய்யப்பட்ட இடைமுகத்தைப் பார்ப்பார். அனைத்து மாற்றங்களும் நினைவகத்தில் கணக்கிடப்பட்டு சேகரிக்கப்பட்டு, கமிட் கட்டத்திற்காகக் காத்திருக்கின்றன.
கட்டம் 2: கமிட் கட்டம் (ஒத்திசைவான மற்றும் குறுக்கிட முடியாதது)
ரெண்டர் கட்டம் முழு புதுப்பிக்கப்பட்ட மரத்திற்கும் குறுக்கீடு இல்லாமல் முடிந்ததும், React கமிட் கட்டத்திற்குச் செல்கிறது. இந்தக் கட்டத்தில், அது சேகரித்த பக்க விளைவுகளின் பட்டியலை எடுத்து DOM-இல் பயன்படுத்துகிறது.
இந்தக் கட்டம் ஒத்திசைவானது மற்றும் குறுக்கிட முடியாது. DOM அணுவியல் ரீதியாக (atomically) புதுப்பிக்கப்படுவதை உறுதி செய்ய, இது ஒரு ஒற்றை, வேகமான வெடிப்பில் செயல்படுத்தப்பட வேண்டும். இது பயனர் ஒரு சீரற்ற அல்லது பகுதி புதுப்பிக்கப்பட்ட UI-ஐப் பார்ப்பதைத் தடுக்கிறது. இதுதான் React, `componentDidMount` மற்றும் `componentDidUpdate` போன்ற லைஃப்சைக்கிள் மெத்தட்களையும், `useLayoutEffect` ஹூக்கையும் இயக்கும் நேரமாகும். இது ஒத்திசைவானது என்பதால், `useLayoutEffect`-இல் நீண்ட நேரம் இயங்கும் குறியீட்டைத் தவிர்க்க வேண்டும், ஏனெனில் அது பெயிண்டிங்கைத் தடுக்கக்கூடும்.
கமிட் கட்டம் முடிந்து DOM புதுப்பிக்கப்பட்ட பிறகு, React `useEffect` ஹூக்குகளை ஒத்திசைவற்ற முறையில் இயங்கும்படி திட்டமிடுகிறது. இது `useEffect`-க்குள் உள்ள எந்தக் குறியீடும் (தரவுப் பெறுதல் போன்றவை) புதுப்பிக்கப்பட்ட UI-ஐ திரையில் காட்டுவதிலிருந்து உலாவியைத் தடுக்காமல் இருப்பதை உறுதி செய்கிறது.
நடைமுறை தாக்கங்கள் மற்றும் API கட்டுப்பாடு
கோட்பாட்டைப் புரிந்துகொள்வது சிறந்தது, ஆனால் உலகளாவிய குழுக்களில் உள்ள டெவலப்பர்கள் இந்த சக்திவாய்ந்த அமைப்பை எவ்வாறு பயன்படுத்த முடியும்? React 18 பல API-களை அறிமுகப்படுத்தியது, அவை டெவலப்பர்களுக்கு ரெண்டரிங் முன்னுரிமையின் மீது நேரடிக் கட்டுப்பாட்டைக் கொடுக்கின்றன.
தானியங்கி பேட்சிங்
React 18-இல், அனைத்து நிலை புதுப்பிப்புகளும் எங்கிருந்து வந்தாலும் தானாகவே பேட்ச் செய்யப்படுகின்றன. முன்பு, React நிகழ்வு கையாளுநர்களுக்குள் உள்ள புதுப்பிப்புகள் மட்டுமே பேட்ச் செய்யப்பட்டன. ப்ராமிஸ்கள், `setTimeout`, அல்லது நேட்டிவ் நிகழ்வு கையாளுநர்களுக்குள் உள்ள புதுப்பிப்புகள் ஒவ்வொன்றும் ஒரு தனி மறு-ரெண்டரைத் தூண்டும். இப்போது, ஷெட்யூலருக்கு நன்றி, React ஒரு "டிக்" காத்திருந்து, அந்த டிக்கிற்குள் நடக்கும் அனைத்து நிலை புதுப்பிப்புகளையும் ஒரே, உகந்த மறு-ரெண்டராக பேட்ச் செய்கிறது. இது தேவையற்ற ரெண்டர்களைக் குறைத்து, இயல்பாகவே செயல்திறனை மேம்படுத்துகிறது.
`startTransition` API
ரெண்டரிங் முன்னுரிமையைக் கட்டுப்படுத்துவதற்கான மிக முக்கியமான API இதுவாக இருக்கலாம். `startTransition` ஒரு குறிப்பிட்ட நிலை புதுப்பிப்பை அவசரமற்றதாக அல்லது ஒரு "டிரான்ஸிஷன்" ஆகக் குறிக்க உங்களை அனுமதிக்கிறது.
ஒரு தேடல் உள்ளீட்டுப் புலத்தை கற்பனை செய்து பாருங்கள். பயனர் தட்டச்சு செய்யும்போது, இரண்டு விஷயங்கள் நடக்க வேண்டும்: 1. புதிய எழுத்தைக் காட்ட உள்ளீட்டுப் புலம் தானாகவே புதுப்பிக்கப்பட வேண்டும் (உயர் முன்னுரிமை). 2. தேடல் முடிவுகளின் பட்டியல் வடிகட்டப்பட்டு மீண்டும் ரெண்டர் செய்யப்பட வேண்டும், இது ஒரு மெதுவான செயலாக இருக்கலாம் (குறைந்த முன்னுரிமை).
`startTransition` இல்லாமல், இரண்டு புதுப்பிப்புகளுக்கும் ஒரே முன்னுரிமை இருக்கும், மேலும் மெதுவாக ரெண்டர் ஆகும் பட்டியல் உள்ளீட்டுப் புலம் பின்தங்கக் காரணமாகி, ஒரு மோசமான பயனர் அனுபவத்தை உருவாக்கும். பட்டியல் புதுப்பிப்பை `startTransition`-க்குள் வைப்பதன் மூலம், நீங்கள் React-க்குச் சொல்கிறீர்கள்: "இந்த புதுப்பிப்பு முக்கியமானது அல்ல. புதிய பட்டியலை நீங்கள் தயாரிக்கும் போது பழைய பட்டியலை ஒரு கணம் காட்டுவது பரவாயில்லை. உள்ளீட்டுப் புலத்தை பதிலளிக்க வைப்பதற்கு முன்னுரிமை கொடுங்கள்."
இதோ ஒரு நடைமுறை உதாரணம்:
தேடல் முடிவுகள் ஏற்றப்படுகின்றன...
import { useState, useTransition } from 'react';
function SearchPage() {
const [isPending, startTransition] = useTransition();
const [inputValue, setInputValue] = useState('');
const [searchQuery, setSearchQuery] = useState('');
const handleInputChange = (e) => {
// உயர்-முன்னுரிமை புதுப்பிப்பு: உள்ளீட்டுப் புலத்தை உடனடியாகப் புதுப்பிக்கவும்
setInputValue(e.target.value);
// குறைந்த-முன்னுரிமை புதுப்பிப்பு: மெதுவான நிலை புதுப்பிப்பை ஒரு டிரான்ஸிஷனில் வைக்கவும்
startTransition(() => {
setSearchQuery(e.target.value);
});
};
return (
இந்தக் குறியீட்டில், `setInputValue` ஒரு உயர்-முன்னுரிமை புதுப்பிப்பு, உள்ளீடு ஒருபோதும் பின்தங்காமல் இருப்பதை உறுதி செய்கிறது. மெதுவாக இருக்கக்கூடிய `SearchResults` காம்போனென்ட்டை மீண்டும் ரெண்டர் செய்யத் தூண்டும் `setSearchQuery`, ஒரு டிரான்ஸிஷனாகக் குறிக்கப்பட்டுள்ளது. பயனர் மீண்டும் தட்டச்சு செய்தால், React இந்த டிரான்ஸிஷனை குறுக்கிட்டு, காலாவதியான ரெண்டர் வேலையைத் தூக்கி எறிந்து, புதிய வினவலுடன் புதிதாகத் தொடங்கலாம். `useTransition` ஹூக் வழங்கும் `isPending` கொடி, இந்த டிரான்ஸிஷனின் போது பயனருக்கு ஒரு லோடிங் நிலையைக் காட்ட ஒரு வசதியான வழியாகும்.
`useDeferredValue` ஹூக்
`useDeferredValue` இதேபோன்ற ஒரு விளைவை அடைய வேறு வழியை வழங்குகிறது. இது மரத்தின் ஒரு முக்கியமற்ற பகுதியை மீண்டும் ரெண்டர் செய்வதைத் தாமதப்படுத்த உங்களை அனுமதிக்கிறது. இது ஒரு டிபவுன்ஸைப் பயன்படுத்துவது போன்றது, ஆனால் இது React-இன் ஷெட்யூலருடன் நேரடியாக ஒருங்கிணைக்கப்பட்டிருப்பதால் மிகவும் புத்திசாலித்தனமானது.
இது ஒரு மதிப்பை எடுத்து, அந்த மதிப்பின் புதிய நகலைத் திருப்பித் தருகிறது, அது ஒரு ரெண்டரின் போது அசல் மதிப்பிலிருந்து "பின்தங்கியிருக்கும்". தற்போதைய ரெண்டர் ஒரு அவசரப் புதுப்பிப்பால் (பயனர் உள்ளீடு போன்றவை) தூண்டப்பட்டால், React முதலில் பழைய, தாமதமான மதிப்புடன் ரெண்டர் செய்து, பின்னர் குறைந்த முன்னுரிமையில் புதிய மதிப்புடன் ஒரு மறு-ரெண்டரைத் திட்டமிடும்.
`useDeferredValue` பயன்படுத்தி தேடல் உதாரணத்தை மறுசீரமைப்போம்:
import { useState, useDeferredValue } from 'react';
function SearchPage() {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
const handleInputChange = (e) => {
setQuery(e.target.value);
};
return (
இங்கே, `input` எப்போதும் சமீபத்திய `query` உடன் புதுப்பித்த நிலையில் உள்ளது. இருப்பினும், `SearchResults` `deferredQuery`-ஐப் பெறுகிறது. பயனர் வேகமாகத் தட்டச்சு செய்யும்போது, `query` ஒவ்வொரு விசை அழுத்தத்திலும் புதுப்பிக்கப்படுகிறது, ஆனால் React-க்கு ஒரு கணம் கிடைக்கும் வரை `deferredQuery` அதன் முந்தைய மதிப்பைக் கொண்டிருக்கும். இது பட்டியலின் ரெண்டரிங்கிற்கு முன்னுரிமையைக் குறைத்து, UI-ஐ தடையின்றி வைக்கிறது.
முன்னுரிமைப் பாதைகளைக் காட்சிப்படுத்துதல்: ஒரு மன மாதிரி
இந்த மன மாதிரியை உறுதிப்படுத்த ஒரு சிக்கலான சூழ்நிலையைப் பார்ப்போம். ஒரு சமூக ஊடக ஊட்டச் செயலியை கற்பனை செய்து பாருங்கள்:
- ஆரம்ப நிலை: பயனர் ஒரு நீண்ட இடுகைகளின் பட்டியலை ஸ்க்ரோல் செய்கிறார். இது பார்வைக்கு வரும் புதிய உருப்படிகளை ரெண்டர் செய்ய `NormalPriority` புதுப்பிப்புகளைத் தூண்டுகிறது.
- உயர்-முன்னுரிமை குறுக்கீடு: ஸ்க்ரோல் செய்யும்போது, பயனர் ஒரு இடுகையின் கருத்துப் பெட்டியில் ஒரு கருத்தைத் தட்டச்சு செய்ய முடிவு செய்கிறார். இந்த தட்டச்சு நடவடிக்கை உள்ளீட்டுப் புலத்திற்கு `ImmediatePriority` புதுப்பிப்புகளைத் தூண்டுகிறது.
- ஒரே நேரத்தில் குறைந்த-முன்னுரிமை வேலை: கருத்துப் பெட்டியில் வடிவமைக்கப்பட்ட உரையின் நேரடி முன்னோட்டத்தைக் காட்டும் ஒரு அம்சம் இருக்கலாம். இந்த முன்னோட்டத்தை ரெண்டர் செய்வது மெதுவாக இருக்கலாம். முன்னோட்டத்திற்கான நிலை புதுப்பிப்பை நாம் `startTransition`-இல் வைக்கலாம், இது அதை `LowPriority` புதுப்பிப்பாக மாற்றுகிறது.
- பின்னணிப் புதுப்பிப்பு: ஒரே நேரத்தில், புதிய இடுகைகளுக்கான ஒரு பின்னணி `fetch` அழைப்பு முடிவடைகிறது, இது ஊட்டத்தின் மேலே "புதிய இடுகைகள் உள்ளன" என்ற பேனரைச் சேர்க்க மற்றொரு `NormalPriority` நிலை புதுப்பிப்பைத் தூண்டுகிறது.
React-இன் ஷெட்யூலர் இந்த டிராஃபிக்கை எவ்வாறு நிர்வகிக்கும் என்பது இதோ:
- React உடனடியாக `NormalPriority` ஸ்க்ரோல் ரெண்டரிங் வேலையை இடைநிறுத்துகிறது.
- இது `ImmediatePriority` உள்ளீட்டுப் புதுப்பிப்புகளை உடனடியாகக் கையாள்கிறது. பயனரின் தட்டச்சு முற்றிலும் பதிலளிக்கக்கூடியதாக உணர்கிறது.
- இது பின்னணியில் `LowPriority` கருத்து முன்னோட்ட ரெண்டரில் வேலையைத் தொடங்குகிறது.
- `fetch` அழைப்பு திரும்பி, பேனருக்கான `NormalPriority` புதுப்பிப்பைத் திட்டமிடுகிறது. இது கருத்து முன்னோட்டத்தை விட அதிக முன்னுரிமை கொண்டிருப்பதால், React முன்னோட்ட ரெண்டரிங்கை இடைநிறுத்தி, பேனர் புதுப்பிப்பில் வேலை செய்து, அதை DOM-இல் கமிட் செய்து, பின்னர் ஓய்வு நேரம் கிடைக்கும்போது முன்னோட்ட ரெண்டரிங்கை மீண்டும் தொடங்கும்.
- அனைத்து பயனர் தொடர்புகளும் மற்றும் உயர்-முன்னுரிமைப் பணிகளும் முடிந்ததும், React அசல் `NormalPriority` ஸ்க்ரோல் ரெண்டரிங் வேலையை விட்ட இடத்திலிருந்து மீண்டும் தொடங்கும்.
வேலையை மாறும் வகையில் இடைநிறுத்துதல், முன்னுரிமைப்படுத்துதல் மற்றும் மீண்டும் தொடங்குதல் ஆகியவை முன்னுரிமைப் பாதை மேலாண்மையின் சாராம்சமாகும். மிக முக்கியமான தொடர்புகள் குறைவான முக்கியமான பின்னணிப் பணிகளால் ஒருபோதும் தடுக்கப்படாததால், செயல்திறன் பற்றிய பயனரின் கருத்து எப்போதும் உகந்ததாக இருப்பதை இது உறுதி செய்கிறது.
உலகளாவிய தாக்கம்: வேகத்தையும் கடந்து
React-இன் கன்கரண்ட் ரெண்டரிங் மாடலின் நன்மைகள் செயலிகளை வேகமாக உணர வைப்பதைத் தாண்டி நீள்கின்றன. அவை உலகளாவிய பயனர் தளத்திற்கான முக்கிய வணிக மற்றும் தயாரிப்பு அளவீடுகளில் ஒரு தெளிவான தாக்கத்தை ஏற்படுத்துகின்றன.
- அணுகல்தன்மை: ஒரு பதிலளிக்கக்கூடிய UI என்பது ஒரு அணுகக்கூடிய UI ஆகும். ஒரு இடைமுகம் முடங்கும்போது, அது அனைத்து பயனர்களுக்கும் குழப்பமாகவும் பயன்படுத்த முடியாததாகவும் இருக்கலாம், ஆனால் ஸ்கிரீன் ரீடர்கள் போன்ற உதவித் தொழில்நுட்பங்களைச் சார்ந்திருப்பவர்களுக்கு இது குறிப்பாக சிக்கலானது, அவை சூழலை இழக்கலாம் அல்லது பதிலளிக்காமல் போகலாம்.
- பயனர் தக்கவைப்பு: ஒரு போட்டி நிறைந்த டிஜிட்டல் உலகில், செயல்திறன் ஒரு அம்சமாகும். மெதுவான, ஜேங்கான செயலிகள் பயனர் விரக்தி, அதிக பவுன்ஸ் விகிதங்கள் மற்றும் குறைந்த ஈடுபாட்டிற்கு வழிவகுக்கும். ஒரு தடையற்ற அனுபவம் நவீன மென்பொருளின் ஒரு முக்கிய எதிர்பார்ப்பாகும்.
- டெவலப்பர் அனுபவம்: இந்த சக்திவாய்ந்த திட்டமிடல் அடிப்படைகளை லைப்ரரியிலேயே உருவாக்குவதன் மூலம், React டெவலப்பர்களை சிக்கலான, செயல்திறன் மிக்க UI-களை மிகவும் அறிவிப்பு ரீதியாக (declaratively) உருவாக்க அனுமதிக்கிறது. சிக்கலான டிபவுன்சிங், த்ராட்லிங், அல்லது `requestIdleCallback` லாஜிக்கை கைமுறையாக செயல்படுத்துவதற்குப் பதிலாக, டெவலப்பர்கள் `startTransition` போன்ற API-களைப் பயன்படுத்தி React-க்கு தங்கள் நோக்கத்தை சிக்னல் செய்யலாம், இது சுத்தமான, பராமரிக்க எளிதான குறியீட்டிற்கு வழிவகுக்கிறது.
உலகளாவிய டெவலப்மெண்ட் குழுக்களுக்கான செயல்படுத்தக்கூடிய குறிப்புகள்
- கன்கரன்சியை ஏற்றுக்கொள்ளுங்கள்: உங்கள் குழு React 18-ஐப் பயன்படுத்துவதையும் புதிய கன்கரண்ட் அம்சங்களைப் புரிந்துகொள்வதையும் உறுதிப்படுத்திக் கொள்ளுங்கள். இது ஒரு முன்னுதாரண மாற்றம்.
- டிரான்ஸிஷன்களை அடையாளம் காணுங்கள்: அவசரம் இல்லாத எந்த UI புதுப்பிப்புகளுக்கும் உங்கள் செயலியைத் தணிக்கை செய்யுங்கள். தொடர்புடைய நிலை புதுப்பிப்புகளை `startTransition`-இல் வைத்து, அவை முக்கியமான தொடர்புகளைத் தடுப்பதைத் தடுக்கவும்.
- கனமான ரெண்டர்களைத் தாமதப்படுத்துங்கள்: மெதுவாக ரெண்டர் ஆகும் மற்றும் வேகமாக மாறும் தரவைச் சார்ந்திருக்கும் காம்போனென்ட்களுக்கு, `useDeferredValue`-ஐப் பயன்படுத்தி அவற்றின் மறு-ரெண்டரிங்கிற்கு முன்னுரிமையைக் குறைத்து, மீதமுள்ள செயலியை சுறுசுறுப்பாக வைத்திருக்கவும்.
- சுயவிவரம் மற்றும் அளவிடுதல்: உங்கள் காம்போனென்ட்கள் எவ்வாறு ரெண்டர் ஆகின்றன என்பதை காட்சிப்படுத்த React DevTools Profiler-ஐப் பயன்படுத்தவும். ப்ரொஃபைலர் கன்கரண்ட் React-க்காகப் புதுப்பிக்கப்பட்டுள்ளது, மேலும் எந்த புதுப்பிப்புகள் குறுக்கிடப்படுகின்றன மற்றும் எவை செயல்திறன் தடைகளை ஏற்படுத்துகின்றன என்பதை அடையாளம் காண உதவும்.
- கல்வியூட்டி மற்றும் பரப்புரை செய்யுங்கள்: இந்த கருத்துக்களை உங்கள் குழுவிற்குள் ஊக்குவிக்கவும். செயல்திறன் மிக்க செயலிகளை உருவாக்குவது ஒரு கூட்டுப் பொறுப்பாகும், மேலும் React-இன் ஷெட்யூலர் பற்றிய ஒரு பகிரப்பட்ட புரிதல் உகந்த குறியீட்டை எழுதுவதற்கு முக்கியமானது.
முடிவுரை
React Fiber மற்றும் அதன் முன்னுரிமை அடிப்படையிலான ஷெட்யூலர், ஃப்ரண்ட்-எண்ட் ஃபிரேம்வொர்க்குகளின் பரிணாம வளர்ச்சியில் ஒரு மகத்தான முன்னேற்றத்தைக் குறிக்கின்றன. தடுக்கும், ஒத்திசைவான ரெண்டரிங் உலகில் இருந்து, கூட்டுறவு, குறுக்கிடக்கூடிய திட்டமிடலின் ஒரு புதிய முன்னுதாரணத்திற்கு நாம் நகர்ந்துள்ளோம். வேலையை நிர்வகிக்கக்கூடிய ஃபைபர் துண்டுகளாகப் பிரித்து, அந்த வேலைக்கு முன்னுரிமை அளிக்க ஒரு அதிநவீன லேன் மாடலைப் பயன்படுத்துவதன் மூலம், React பயனர் எதிர்கொள்ளும் தொடர்புகள் எப்போதும் முதலில் கையாளப்படுவதை உறுதி செய்ய முடியும், பின்னணியில் சிக்கலான பணிகளைச் செய்யும்போது கூட, தடையற்ற மற்றும் உடனடி உணர்வைக் கொடுக்கும் செயலிகளை உருவாக்குகிறது.
டெவலப்பர்களுக்கு, டிரான்ஸிஷன்கள் மற்றும் தாமதமான மதிப்புகள் போன்ற கருத்துக்களில் தேர்ச்சி பெறுவது இனி ஒரு விருப்பத் தேர்வு அல்ல—இது நவீன, உயர்-செயல்திறன் கொண்ட வலைச் செயலிகளை உருவாக்குவதற்கான ஒரு முக்கியத் திறமையாகும். React-இன் முன்னுரிமைப் பாதை மேலாண்மையைப் புரிந்துகொண்டு பயன்படுத்துவதன் மூலம், நீங்கள் உலகளாவிய பார்வையாளர்களுக்கு ஒரு சிறந்த பயனர் அனுபவத்தை வழங்க முடியும், செயல்பாட்டு ரீதியாக மட்டுமல்லாமல், உண்மையிலேயே பயன்படுத்த மகிழ்ச்சியாக இருக்கும் இடைமுகங்களை உருவாக்கலாம்.